#include <sys/time.h>
#include <sys/syscall.h>
#include <sys/proc.h>
#include <sys/times.h>
#include <time.h>
#include <types.h>
#include <errno.h>
#include <sys/walltime.h>
#include <sys/time.h>

uint64_t alarm(uint64_t second)
{
    return syscall1(uint64_t, SYS_ALARM, second);
}

int walltime(walltime_t *walltime)
{
    return syscall1(int, SYS_GETWALLTIME, (uintptr_t)walltime);
}

clock_t getticks()
{
    return syscall0(clock_t, SYS_GETTICKS);
}

int gettimeofday(timeval_t *tv, timezone_t *tz)
{
    return syscall2(int, SYS_GETTIMEOFDAY, (uintptr_t)tv, (uintptr_t)tz);
}

int clock_gettime(clock_type_t clockid, timespec_t *ts)
{
    return syscall2(int, SYS_CLOCK_GETTIME, clockid, (uintptr_t)ts);
}

int walltime_switch(walltime_t *walltime, tm_t *tm)
{
    if (!walltime || !tm)
        return -1;
    tm->tm_year = walltime->year;
    tm->tm_yday = walltime->year_days;
    tm->tm_mon = walltime->month;
    tm->tm_mday = walltime->day;
    tm->tm_wday = walltime->week_days;
    tm->tm_hour = walltime->hour;
    tm->tm_min = walltime->minute;
    tm->tm_sec = walltime->second;
    tm->tm_isdast = -1;
    return 0;
}

int usleep(uint32_t usec)
{
    timeval_t tvin, tvout;
    uint64_t val;

    tvin.tv_sec = usec / 1000000L;
    tvin.tv_usec = usec % 1000000L;

    val = syscall2(int, SYS_USLEEP, (uintptr_t)&tvin, (uintptr_t)&tvout);
    if (!val)
        return 0;

    _set_errno(val);
    return -1;
}

void Mdelay(time_t msec)
{
    clock_t ticks = MSEC_TO_TICKS(msec);
    if (!ticks)
        ticks = 1;
    clock_t start = getticks();
    while (getticks() - start < ticks)
    {
        sched_yeild();
    }
}